/*
 * @Author: Lingma 
 * @Date: 2025-09-04
 * @Description: ThreadX Shell System implementation
 */

#include "shell.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "bsp_uart.h"
#include "compoent_config.h"
#include "tx_block_pool.h"
#include "tx_byte_pool.h"
#include "tx_event_flags.h"
#include "tx_mutex.h"
#include "tx_queue.h"
#include "tx_semaphore.h"
#include "tx_thread.h"
#include "tx_timer.h"

// 全局shell上下文
static shell_context_t g_shell_ctx;
static CHAR *shell_thread_stack = NULL;
static uint8_t shell_rx_buffer[2][2]; // 双缓冲区，每个缓冲区2字节

// 内置命令表
static const shell_cmd_t g_shell_cmds[] = {
    {"help", shell_help_cmd, "显示帮助信息"},
    {"clear", shell_clear_cmd, "清屏"},
    {"version", shell_version_cmd, "显示版本信息"},
     {"ps", shell_ps_cmd, "显示系统对象信息"},
    {NULL, NULL, NULL} // 结束标记
};

// 动态注册命令表
static shell_cmd_t g_dynamic_shell_cmds[SHELL_MAX_DYNAMIC_COMMANDS];
static int g_dynamic_cmd_count = 0;

// 内部函数声明
static void shell_thread_entry(ULONG input);
static void shell_parse_cmd(void);
static void shell_execute_cmd(void);
static void shell_print_prompt(void);
static int shell_split_args(char *cmdline);
static const shell_cmd_t* shell_find_cmd(const char *name);
static void shell_handle_char(char ch);

// 跟踪按键序列
static uint8_t g_escape_sequence = 0;  // 跟踪是否收到ESC字符

// 处理单个字符输入
static void shell_handle_char(char ch) {
    // 处理转义序列（箭头键）
    if (g_escape_sequence == 1) {
        if (ch == '[') {
            g_escape_sequence = 2;
            return;
        } else {
            g_escape_sequence = 0;  // 重置状态
        }
    } else if (g_escape_sequence == 2) {
        g_escape_sequence = 0;  // 重置状态
        switch (ch) {
            case 'A': // 上箭头键
                if (g_shell_ctx.history_count > 0) {
                    if (g_shell_ctx.history_index > 0) {
                        g_shell_ctx.history_index--;
                    } else {
                        return; // 已经在最顶部的历史记录
                    }
                    
                    // 清除当前行
                    for (int i = 0; i < g_shell_ctx.cmd_len; i++) {
                        shell_printf("\b \b");
                    }
                    
                    // 显示历史命令
                    strcpy(g_shell_ctx.cmd_buffer, g_shell_ctx.history[g_shell_ctx.history_index]);
                    g_shell_ctx.cmd_len = strlen(g_shell_ctx.cmd_buffer);
                    shell_printf("%s", g_shell_ctx.cmd_buffer);
                }
                return;
                
            case 'B': // 下箭头键
                if (g_shell_ctx.history_count > 0) {
                    if (g_shell_ctx.history_index < g_shell_ctx.history_count - 1) {
                        g_shell_ctx.history_index++;
                    } else if (g_shell_ctx.history_index == g_shell_ctx.history_count - 1) {
                        g_shell_ctx.history_index++; // 移动到"当前编辑行"
                    } else {
                        return; // 已经在最底部
                    }
                    
                    // 清除当前行
                    for (int i = 0; i < g_shell_ctx.cmd_len; i++) {
                        shell_printf("\b \b");
                    }
                    
                    // 如果是"当前编辑行"则清空，否则显示历史命令
                    if (g_shell_ctx.history_index == g_shell_ctx.history_count) {
                        g_shell_ctx.cmd_len = 0;
                        g_shell_ctx.cmd_buffer[0] = '\0';
                    } else {
                        strcpy(g_shell_ctx.cmd_buffer, g_shell_ctx.history[g_shell_ctx.history_index]);
                        g_shell_ctx.cmd_len = strlen(g_shell_ctx.cmd_buffer);
                        shell_printf("%s", g_shell_ctx.cmd_buffer);
                    }
                }
                return;
                
            default:
                return;
        }
    }
    
    switch (ch) {
        case '\033': // ESC字符
            g_escape_sequence = 1;
            return;
            
        case '\r': // 回车
        case '\n': // 换行
            if (g_shell_ctx.cmd_len > 0) {
                g_shell_ctx.cmd_buffer[g_shell_ctx.cmd_len] = '\0';
                shell_printf("\r\n");
                shell_parse_cmd();
                shell_execute_cmd();
                // 添加到历史命令
                if (g_shell_ctx.history_count < SHELL_HISTORY_MAX) {
                    strcpy(g_shell_ctx.history[g_shell_ctx.history_count], g_shell_ctx.cmd_buffer);
                    g_shell_ctx.history_count++;
                } else {
                    // 循环替换历史命令
                    for (int i = 0; i < SHELL_HISTORY_MAX - 1; i++) {
                        strcpy(g_shell_ctx.history[i], g_shell_ctx.history[i+1]);
                    }
                    strcpy(g_shell_ctx.history[SHELL_HISTORY_MAX-1], g_shell_ctx.cmd_buffer);
                }
                g_shell_ctx.history_index = g_shell_ctx.history_count;
            } else {
                // 即使命令为空也要换行
                shell_printf("\r\n");
            }
            g_shell_ctx.cmd_len = 0;
            shell_print_prompt();
            break;
            
        case '\b': // 退格
        case 127:  // 删除
            if (g_shell_ctx.cmd_len > 0) {
                g_shell_ctx.cmd_len--;
                // 发送退格、空格、再退格的序列来正确删除字符
                shell_printf("\b \b");
            }
            break;
            
        case '\t': // 制表符自动补全
            // TODO: 实现自动补全功能
            break;
            
        case 0x03: // Ctrl+C
            g_shell_ctx.cmd_len = 0;
            shell_printf("^C\r\n");
            shell_print_prompt();
            break;
            
        default:
            if (g_shell_ctx.cmd_len < SHELL_CMD_MAX_LENGTH - 1) {
                if (ch >= 32 && ch <= 126) { // 可打印字符
                    g_shell_ctx.cmd_buffer[g_shell_ctx.cmd_len++] = ch;
                    shell_printf("%c", ch);
                }
            }
            break;
    }
}


// 初始化shell
void shell_init() {
    // 初始化上下文
    memset(&g_shell_ctx, 0, sizeof(g_shell_ctx));
    // 初始化动态命令表
    memset(g_dynamic_shell_cmds, 0, sizeof(g_dynamic_shell_cmds));
    g_dynamic_cmd_count = 0;

    // 初始化UART设备用于shell
    UART_Device_init_config uart_config = {
        .huart = &SHELL_UART,  // 使用日志串口
        .expected_len = 1,           // 每次接收1个字节
        .rx_buf = (uint8_t (*)[2])shell_rx_buffer,
        .rx_buf_size = 1,
        .rx_mode = UART_MODE_IT,
        .tx_mode = UART_MODE_BLOCKING,
        .timeout = 1000,
        .rx_complete_cb = NULL,
        .cb_type = UART_CALLBACK_EVENT,
        .event_flag = UART_RX_DONE_EVENT
    };
    
    g_shell_ctx.uart_dev = BSP_UART_Device_Init(&uart_config);
    g_shell_ctx.running = false;
    g_shell_ctx.initialized = true;
    
    // 创建互斥锁
    tx_mutex_create(&g_shell_ctx.mutex, "Shell Mutex", TX_NO_INHERIT);
    
    // 分配线程栈
    shell_thread_stack = threadx_malloc(SHELL_THREAD_STACK_SIZE);
    if (shell_thread_stack== NULL) {return;}
    
    // 创建shell线程
    tx_thread_create(&g_shell_ctx.thread, "Shell Thread",shell_thread_entry,0,shell_thread_stack,
                     SHELL_THREAD_STACK_SIZE,SHELL_THREAD_PRIORITY, SHELL_THREAD_PRIORITY,TX_NO_TIME_SLICE,TX_AUTO_START); 
    g_shell_ctx.running = true;
    shell_printf("\r\n");
    shell_printf("  __  __    _    ____\r\n");
    shell_printf(" |  \\/  |  / \\  / ___|\r\n");
    shell_printf(" | |\\/| | / _ \\ \\___ \\\r\n");
    shell_printf(" | |  | |/ ___ \\ ___) |\r\n");
    shell_printf(" |_|  |_/_/   \\_\\____/\r\n");
    shell_printf("\r\n");
    shell_print_prompt();
}

// shell线程入口函数
static void shell_thread_entry(ULONG input) {
    while (g_shell_ctx.running && g_shell_ctx.initialized) {
        ULONG actual_flags = 0;
        // 等待事件标志，自动清除
        UINT status = tx_event_flags_get(
                &g_shell_ctx.uart_dev->rx_event, // 事件组
                UART_RX_DONE_EVENT,
                TX_OR_CLEAR,      // 自动清除
                &actual_flags,
                TX_WAIT_FOREVER   // 无限等待
        );
        if ((status == TX_SUCCESS) && (actual_flags & UART_RX_DONE_EVENT)) {
            char ch = g_shell_ctx.uart_dev->rx_buf[!g_shell_ctx.uart_dev->rx_active_buf][0];
            shell_handle_char(ch);
        }
    }
}

// 打印提示符
static void shell_print_prompt(void) {
    if (!g_shell_ctx.initialized) {
        return;
    }
    
    shell_printf(SHELL_PROMPT);
}

// 解析命令
static void shell_parse_cmd(void) {
    if (!g_shell_ctx.initialized) {
        return;
    }
    
    g_shell_ctx.argc = shell_split_args(g_shell_ctx.cmd_buffer);
}

// 执行命令
static void shell_execute_cmd(void) {
    if (!g_shell_ctx.initialized || g_shell_ctx.argc == 0) {
        return;
    }
    
    const shell_cmd_t *cmd = shell_find_cmd(g_shell_ctx.args[0]);
    if (cmd != NULL) {
        cmd->func(g_shell_ctx.argc, g_shell_ctx.args);
    } else {
        shell_printf("Unknown command: %s\r\n", g_shell_ctx.args[0]);
    }
}

// 分割参数
static int shell_split_args(char *cmdline) {
    int argc = 0;
    char *token;
    char *saveptr;
    
    if (!cmdline) {
        return 0;
    }
    
    // 处理命令行参数
    token = strtok_r(cmdline, " ", &saveptr);
    while (token != NULL && argc < SHELL_MAX_ARGS) {
        g_shell_ctx.args[argc++] = token;
        token = strtok_r(NULL, " ", &saveptr);
    }
    
    return argc;
}

// 查找命令（包括内置命令和动态注册命令）
static const shell_cmd_t* shell_find_cmd(const char *name) {
    if (!name) {
        return NULL;
    }
    
    // 先在内置命令表中查找
    for (int i = 0; g_shell_cmds[i].name != NULL; i++) {
        if (strcmp(g_shell_cmds[i].name, name) == 0) {
            return &g_shell_cmds[i];
        }
    }
    
    // 再在动态注册命令表中查找
    for (int i = 0; i < g_dynamic_cmd_count; i++) {
        if (g_dynamic_shell_cmds[i].name && strcmp(g_dynamic_shell_cmds[i].name, name) == 0) {
            return &g_dynamic_shell_cmds[i];
        }
    }
    
    return NULL;
}

// 格式化打印函数
void shell_printf(const char *fmt, ...) {
    char buffer[256];
    va_list args;
    int len;
    
    if (!g_shell_ctx.initialized || !fmt) {
        return;
    }
    
    va_start(args, fmt);
    len = vsnprintf(buffer, sizeof(buffer), fmt, args);
    va_end(args);
    
    if (len > 0 && g_shell_ctx.uart_dev) {
        tx_mutex_get(&g_shell_ctx.mutex, TX_WAIT_FOREVER);
        BSP_UART_Send(g_shell_ctx.uart_dev, (uint8_t*)buffer, (uint16_t)len);
        tx_mutex_put(&g_shell_ctx.mutex);
    }
}

void shell_uart_send(const uint8_t *data, uint16_t len) {
    if (len > 0 && g_shell_ctx.uart_dev) {
        tx_mutex_get(&g_shell_ctx.mutex, TX_WAIT_FOREVER);
        BSP_UART_Send(g_shell_ctx.uart_dev, (uint8_t*)data, len);
        tx_mutex_put(&g_shell_ctx.mutex);
    }
}


// help命令实现
void shell_help_cmd(int argc, char **argv) {
    shell_printf("Available commands:\r\n");
    
    // 显示内置命令
    for (int i = 0; g_shell_cmds[i].name != NULL; i++) {
        shell_printf("  %-10s - %s\r\n", g_shell_cmds[i].name, g_shell_cmds[i].description);
    }
    
    // 显示动态注册命令
    for (int i = 0; i < g_dynamic_cmd_count; i++) {
        if (g_dynamic_shell_cmds[i].name) {
            shell_printf("  %-10s - %s\r\n", g_dynamic_shell_cmds[i].name, 
                         g_dynamic_shell_cmds[i].description ? g_dynamic_shell_cmds[i].description : "No description");
        }
    }
    
    shell_printf("\r\n");
}

// clear命令实现
void shell_clear_cmd(int argc, char **argv) {
    // 发送ANSI清屏序列
    shell_printf("\033[2J\033[H");
}

// version命令实现
void shell_version_cmd(int argc, char **argv) {
    shell_printf("ThreadX Shell System v1.0\r\n");
    shell_printf("Built with uLog threadx\r\n");
}

// 注册函数接口
int shell_register_function(const char* name, shell_cmd_func_t func, const char* description) {
    // 检查参数
    if (!name || !func) {
        return -1;
    }
    
    // 检查是否已达到最大命令数
    if (g_dynamic_cmd_count >= SHELL_MAX_DYNAMIC_COMMANDS) {
        shell_printf("Error: Maximum number of dynamic commands reached.\r\n");
        return -1;
    }
    
    // 检查命令是否已存在
    if (shell_find_cmd(name) != NULL) {
        shell_printf("Error: Command '%s' already exists.\r\n", name);
        return -1;
    }
    
    // 添加命令到动态命令表
    g_dynamic_shell_cmds[g_dynamic_cmd_count].name = name;
    g_dynamic_shell_cmds[g_dynamic_cmd_count].func = func;
    g_dynamic_shell_cmds[g_dynamic_cmd_count].description = description;
    g_dynamic_cmd_count++;
    
    return 0;
}

// ps命令实现
void shell_ps_cmd(int argc, char **argv) {
    if (argc < 2) {
        // 显示基本帮助信息
        shell_printf("Usage: ps <object_type>\r\n");
        shell_printf("Object types: thread, timer, mutex, sem, event, queue, bytepool, blockpool\r\n");
        return;
    }
    
    if (strcmp(argv[1], "thread") == 0) {
        // 显示线程信息
        shell_printf("Thread Information:\r\n");
        shell_printf("%-16s %-8s %-10s %-8s %-8s\r\n", "Name", "State", "Priority", "Stack", "Run Count");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_THREAD *thread_ptr = _tx_thread_created_ptr;
        if (thread_ptr) {
            do {
                CHAR *name;
                UINT state;
                ULONG run_count;
                UINT priority;
                UINT preempt_threshold; 
                ULONG time_slice;
                TX_THREAD *next_thread;
                
                // 获取线程信息
                UINT status = tx_thread_info_get(thread_ptr, &name, &state, &run_count, 
                                                &priority, &preempt_threshold, &time_slice, 
                                                TX_NULL, &next_thread);
                
                if (status == TX_SUCCESS) {
                    char state_str[16];
                    switch (state) {
                        case TX_READY:
                            strcpy(state_str, "READY");
                            break;
                        case TX_COMPLETED:
                            strcpy(state_str, "COMPLETED");
                            break;
                        case TX_TERMINATED:
                            strcpy(state_str, "TERMINATED");
                            break;
                        case TX_SUSPENDED:
                            strcpy(state_str, "SUSPENDED");
                            break;
                        case TX_SLEEP:
                            strcpy(state_str, "SLEEP");
                            break;
                        default:
                            strcpy(state_str, "UNKNOWN");
                            break;
                    }
                    
                    shell_printf("%-16s %-8s %-10d %-8s %-8lu\r\n", 
                                name ? name : "N/A", 
                                state_str, 
                                priority, 
                                "N/A", 
                                run_count);
                }
                
                thread_ptr = thread_ptr -> tx_thread_created_next;
            } while (thread_ptr != _tx_thread_created_ptr);
        }
    } 
    else if (strcmp(argv[1], "timer") == 0) {
        // 显示定时器信息
        shell_printf("Timer Information:\r\n");
        shell_printf("%-16s %-8s %-12s\r\n", "Name", "Active", "Reschedules");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_TIMER *timer_ptr = _tx_timer_created_ptr;
        if (timer_ptr) {
            do {
                CHAR *name;
                UINT active;
                ULONG remaining_ticks;
                ULONG reschedule_ticks;
                TX_TIMER *next_timer;
                
                UINT status = tx_timer_info_get(timer_ptr, &name, &active, &remaining_ticks,
                                               &reschedule_ticks, &next_timer);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s %-8s %-12lu\r\n",
                                name ? name : "N/A",
                                active ? "YES" : "NO",
                                reschedule_ticks);
                }
                
                timer_ptr = timer_ptr -> tx_timer_created_next;
            } while (timer_ptr != _tx_timer_created_ptr);
        } else {
            shell_printf("No timers created.\r\n");
        }
    }
    else if (strcmp(argv[1], "mutex") == 0) {
        // 显示互斥量信息
        shell_printf("Mutex Information:\r\n");
        shell_printf("%-16s %-8s %-16s\r\n", "Name", "Count", "Owner");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_MUTEX *mutex_ptr = _tx_mutex_created_ptr;
        if (mutex_ptr) {
            do {
                CHAR *name;
                ULONG count;
                TX_THREAD *owner;
                TX_THREAD *first_suspended;
                ULONG suspended_count;
                TX_MUTEX *next_mutex;
                
                UINT status = tx_mutex_info_get(mutex_ptr, &name, &count, &owner,
                                               &first_suspended, &suspended_count, &next_mutex);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s %-8lu %-16s\r\n",
                                name ? name : "N/A",
                                count,
                                owner ? (owner->tx_thread_name ? owner->tx_thread_name : "N/A") : "NONE");
                }
                
                mutex_ptr = mutex_ptr -> tx_mutex_created_next;
            } while (mutex_ptr != _tx_mutex_created_ptr);
        } else {
            shell_printf("No mutexes created.\r\n");
        }
    }
    else if (strcmp(argv[1], "sem") == 0) {
        // 显示信号量信息
        shell_printf("Semaphore Information:\r\n");
        shell_printf("%-16s %-12s %-12s\r\n", "Name", "Current Count", "Suspended");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_SEMAPHORE *semaphore_ptr = _tx_semaphore_created_ptr;
        if (semaphore_ptr) {
            do {
                CHAR *name;
                ULONG current_value;
                TX_THREAD *first_suspended;
                ULONG suspended_count;
                TX_SEMAPHORE *next_semaphore;
                
                UINT status = tx_semaphore_info_get(semaphore_ptr, &name, &current_value,
                                                   &first_suspended, &suspended_count, &next_semaphore);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s %-12lu %-12lu\r\n",
                                name ? name : "N/A",
                                current_value,
                                suspended_count);
                }
                
                semaphore_ptr = semaphore_ptr -> tx_semaphore_created_next;
            } while (semaphore_ptr != _tx_semaphore_created_ptr);
        } else {
            shell_printf("No semaphores created.\r\n");
        }
    }
    else if (strcmp(argv[1], "event") == 0) {
        // 显示事件标志组信息
        shell_printf("Event Flags Information:\r\n");
        shell_printf("%-16s %-12s %-12s\r\n", "Name", "Current Flags", "Suspended");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_EVENT_FLAGS_GROUP *event_ptr = _tx_event_flags_created_ptr;
        if (event_ptr) {
            do {
                CHAR *name;
                ULONG current_flags;
                TX_THREAD *first_suspended;
                ULONG suspended_count;
                TX_EVENT_FLAGS_GROUP *next_event;
                
                UINT status = tx_event_flags_info_get(event_ptr, &name, &current_flags,
                                                     &first_suspended, &suspended_count, &next_event);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s 0x%-10lx %-12lu\r\n",
                                name ? name : "N/A",
                                current_flags,
                                suspended_count);
                }
                
                event_ptr = event_ptr -> tx_event_flags_group_created_next;
            } while (event_ptr != _tx_event_flags_created_ptr);
        } else {
            shell_printf("No event flags created.\r\n");
        }
    }
    else if (strcmp(argv[1], "queue") == 0) {
        // 显示队列信息
        shell_printf("Queue Information:\r\n");
        shell_printf("%-16s %-10s %-10s %-10s\r\n", "Name", "Enqueued", "Available", "Suspended");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_QUEUE *queue_ptr = _tx_queue_created_ptr;
        if (queue_ptr) {
            do {
                CHAR *name;
                ULONG enqueued;
                ULONG available_storage;
                TX_THREAD *first_suspended;
                ULONG suspended_count;
                TX_QUEUE *next_queue;
                
                UINT status = tx_queue_info_get(queue_ptr, &name, &enqueued, &available_storage,
                                               &first_suspended, &suspended_count, &next_queue);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s %-10lu %-10lu %-10lu\r\n",
                                name ? name : "N/A",
                                enqueued,
                                available_storage,
                                suspended_count);
                }
                
                queue_ptr = queue_ptr -> tx_queue_created_next;
            } while (queue_ptr != _tx_queue_created_ptr);
        } else {
            shell_printf("No queues created.\r\n");
        }
    }
    else if (strcmp(argv[1], "bytepool") == 0) {
        // 显示字节池信息
        shell_printf("Byte Pool Information:\r\n");
        shell_printf("%-16s %-12s %-12s\r\n", "Name", "Available", "Fragments");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_BYTE_POOL *byte_pool_ptr = _tx_byte_pool_created_ptr;
        if (byte_pool_ptr) {
            do {
                CHAR *name;
                ULONG available_bytes;
                ULONG fragments;
                TX_THREAD *first_suspended;
                ULONG suspended_count;
                TX_BYTE_POOL *next_pool;
                
                UINT status = tx_byte_pool_info_get(byte_pool_ptr, &name, &available_bytes,
                                                   &fragments, &first_suspended, 
                                                   &suspended_count, &next_pool);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s %-12lu %-12lu\r\n",
                                name ? name : "N/A",
                                available_bytes,
                                fragments);
                }
                
                byte_pool_ptr = byte_pool_ptr -> tx_byte_pool_created_next;
            } while (byte_pool_ptr != _tx_byte_pool_created_ptr);
        } else {
            shell_printf("No byte pools created.\r\n");
        }
    }
    else if (strcmp(argv[1], "blockpool") == 0) {
        // 显示块池信息
        shell_printf("Block Pool Information:\r\n");
        shell_printf("%-16s %-10s %-10s %-10s\r\n", "Name", "Available", "Total", "Suspended");
        shell_printf("----------------------------------------------------------------\r\n");
        
        TX_BLOCK_POOL *block_pool_ptr = _tx_block_pool_created_ptr;
        if (block_pool_ptr) {
            do {
                CHAR *name;
                ULONG available_blocks;  
                ULONG total_blocks;     
                TX_THREAD *first_suspended;
                ULONG suspended_count;
                TX_BLOCK_POOL *next_pool;
                
                UINT status = tx_block_pool_info_get(block_pool_ptr, &name, &available_blocks,
                                                    &total_blocks, &first_suspended,
                                                    &suspended_count, &next_pool);
                
                if (status == TX_SUCCESS) {
                    shell_printf("%-16s %-10lu %-10lu %-10lu\r\n",
                                name ? name : "N/A",
                                available_blocks,
                                total_blocks,
                                suspended_count);
                }
                
                block_pool_ptr = block_pool_ptr -> tx_block_pool_created_next;
            } while (block_pool_ptr != _tx_block_pool_created_ptr);
        } else {
            shell_printf("No block pools created.\r\n");
        }
    }
    else {
        shell_printf("Unknown object type: %s\r\n", argv[1]);
        shell_printf("Supported types: thread, timer, mutex, sem, event, queue, bytepool, blockpool\r\n");
    }
}
